using System;
using System.Collections.Generic;
using System.Text;
using MeetingRoom.Data;
using MeetingRoom.Domain;
using MeetingRoom.Service;

namespace MeetingRoom.Allocation
{
    public class MeetingRoomAllocator
    {
        protected int minutes;

        protected IGetUpcommingSchedules getUpcomingSchedules = null;

        protected IGetMeetingRoomsByMeetingRoomType getMeetingRoomsByMeetingRoomType = null;

        protected IUpdateSchedule updateSchedule = null;

        protected IMessagingService messagingService = null;

        public MeetingRoomAllocator()
        {

        }

        public int Minutes
        {
            set
            {
                this.minutes = value;
            }
            get
            {
                return this.minutes;
            }
        }

        public IGetUpcommingSchedules GetUpcomingSchedules
        {
            set
            {
                this.getUpcomingSchedules = value;
            }
        }

        public IGetMeetingRoomsByMeetingRoomType GetMeetingRoomsByMeetingRoomType
        {
            set
            {
                this.getMeetingRoomsByMeetingRoomType = value;
            }
        }

        public IUpdateSchedule UpdateSchedule
        {
            set
            {
                this.updateSchedule = value;
            }
        }


        public IMessagingService MessagingService
        {
            set
            {
                this.messagingService = value;
            }
        }

        protected string GetMessage(Schedule schedule)
        {
            return string.Format("You session of {0} will be started on {1}, in room {1}," + 
            "please be on time, thank you!", 
            schedule.Name, schedule.Duration.Begin, schedule.MeetingRoom.Name);
        }

        public int Allocate()
        {
            int totalAllocated = 0;
            // select all the schedules which will be taken in 10 minutes
            // find suitable rooms accroding to the room type request
            // allocate the room for the schedule
            // inform the involved parties

            List<Schedule> schedules =
                this.getUpcomingSchedules.GetUpcomingSchedules(this.minutes);
            foreach (Schedule schedule in schedules)
            {
                List<MeetingRoom.Domain.MeetingRoom> meetingRooms =
                    this.getMeetingRoomsByMeetingRoomType
                    .GetMeetingRoomByMeetingRoomType(schedule.MeetingRoomType);
                if (meetingRooms == null || meetingRooms.Count == 0)
                {
                    //throw new MeetingRoom.Service.MeetingRoomUnavaliableException();
                    continue;
                }

                MeetingRoom.Domain.MeetingRoom meetingRoom = meetingRooms[0];
                meetingRoom.Status = MeetingRoomStatus.UNAVAILABLE;

                schedule.Status = ScheduleStatus.LOCATION_PLANNED;
                schedule.MeetingRoom = meetingRoom;

                this.updateSchedule.Update(schedule);
                totalAllocated++;

                string message = this.GetMessage(schedule);
                this.messagingService.Notify(schedule.Applicant, message);
                this.messagingService.Notify(schedule.Attendees, message);
            }

            return totalAllocated;
        }
    }
}
